Introduction
The GSE133112 dataset was downloaded from GEO using the GEOmetadb package. The dataset contains RNA-seq results from primary AML cells (AML37) treated with a BCL6 inhibitor (FX1), or DMSO and not treated samples as controls. It was filtered for read counts and normalized using the TMM method. Previously, differential gene expression analysis using the exactTest method and an overrepresentation analysis was perfomred to visualize the top gene hits (2871 genes at p < 0.0001) in the FX1 treatment vs. untreated groups.
Setup: Call Packages and Source Data
Install the required packages and source the required data from Assignment 1
1.1: The required packages are installed if they are not already present. Next, all of the packages that will be used subsequently are loaded.
if (!requireNamespace("ComplexHeatmap", quietly = TRUE))
install.packages("ComplexHeatmap")
if (!requireNamespace("circlize", quietly = TRUE))
install.packages("circlize")
if (!requireNamespace("edgeR", quietly = TRUE))
install.packages("edgeR")
if (!requireNamespace("gprofiler2", quietly = TRUE))
install.packages("gprofiler2")
if (!requireNamespace("ggplot2", quietly = TRUE))
install.packages("ggplot2")
if (!requireNamespace("ggrepel", quietly = TRUE))
install.packages("ggrepel")
if (!requireNamespace("RCurl", quietly = TRUE))
install.packages("RCurl")
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
if (!requireNamespace("RCy3", quietly = TRUE))
install.packages("RCy3")
suppressPackageStartupMessages(library(ComplexHeatmap))
suppressPackageStartupMessages(library(circlize))
suppressPackageStartupMessages(library(edgeR))
suppressPackageStartupMessages(library(gprofiler2))
suppressPackageStartupMessages(library(ggplot2))
suppressPackageStartupMessages(library(ggrepel))
suppressPackageStartupMessages(library(RCurl))
suppressPackageStartupMessages(library(BiocManager))
suppressPackageStartupMessages(library(RCy3))
1.2 The variables from Assignment-2 are knitted as the ranked file will be used for downstream analyses.
Non-Thresholded Gene Set Enrichment Analysis
What method did you use? What genesets did you use?
I used Gene Set Enrichment Analysis that is avaialble through the GSEA Java software and the enrichment map protocol pipeline from the Bader Lab (Isserlin, 2020). I used the human gene set available from the Bader Lab.
2.1 An updated geneset file is obtained from the Bader Lab and stored in the working directory. This file will be used in the GSEA.
# code adapted from lecture 10
gmt_url = "http://download.baderlab.org/EM_Genesets/current_release/Human/symbol/"
# list all the files on the server
filenames = getURL(gmt_url)
tc = textConnection(filenames)
contents = readLines(tc)
close(tc)
# get the gmt that has all the pathways and does not include terms inferred
# from electronic annotations(IEA) start with gmt file that has pathways only
rx = gregexpr("(?<=<a href=\")(.*.GOBP_AllPathways_no_GO_iea.*.)(.gmt)(?=\">)", contents,
perl = TRUE)
# set to current working directory
data_dir = "/home/rstudio/projects"
gmt_file = unlist(regmatches(contents, rx))
dest_gmt_file <- file.path(data_dir, gmt_file)
download.file(paste(gmt_url, gmt_file, sep = ""), destfile = dest_gmt_file)
2.2: The ranked list created in Assignmnent-2 is stored as a .rnk file in the working directory.
write.table(x=data.frame(genename = hits_gn$Geneid, F_stat=hits_gn$rank),
file=file.path("/home/rstudio/projects", "expression.rnk"), sep ="\t",
row.names = FALSE, col.names = FALSE, quote = FALSE)
2.3: GSEA is performed on the ranked gene set using the enrichment map protocol pipeline from the Bader Lab (Isserlin, 2020). The following parameters were specified. 1000 permuations were run.
The following code was run on the GSEA Docker (risserlin/em_base_image).
#rnk <- read.table("fx1_ranked_genelist.txt", sep = "\t", header=TRUE)
#write.table(rnk, file="expression.rnk", quote=FALSE, sep="\t", row.names=FALSE)
# specify the java_version
#run_gsea <- TRUE
#java_version = "11"
# set the location of the GSEA java file and specifiy the working directory
#gsea_jar <- "/home/rstudio/GSEA_4.1.0/gsea-cli.sh"
#working_dir <- "/home/rstudio/projects"
# specify the ranked and output analysis file
#rnk_file <- "expression.rnk"
#analysis_name <- "A3_FX1_Results"
# run GSEA
#if(run_gsea && java_version == "11"){
# command <- paste("",gsea_jar, "GSEAPreRanked -gmx", dest_gmt_file, "-rnk" ,file.path(working_dir,rnk_file), "-collapse false -nperm 1000 -scoring_scheme weighted -rpt_label ",analysis_name," -plot_top_x 20 -rnd_seed 12345 -set_max 200 -set_min 15 -zip_report false -out" ,working_dir, " > gsea_output.txt",sep=" ")
# system(command)
#} else if (run_gsea) {
# command <- paste("java -Xmx1G -cp",gsea_jar, "xtools.gsea.GseaPreranked -gmx", dest_gmt_file, "-rnk" ,file.path(working_dir,rnk_file), "-collapse false -nperm 1000 -permute gene_set -scoring_scheme weighted -rpt_label ",analysis_name," -num 100 -plot_top_x 20 -rnd_seed 12345 -set_max 200 -set_min 15 -zip_report false -out" ,working_dir, "-gui false > gsea_output.txt",sep=" ")
# system(command)
#}
Summary of Enrichment Results
2.4: The top upregulated pathway and their FDR q-value are shown from the GSEA.
gsea_file <- list.files(path = getwd(), pattern = "\\.GseaPreranked")
# read the top positively and negatively regulated genes from the GSEA
pos_results <- list.files(path = file.path(getwd(), gsea_file[1]), pattern = "gsea_report_for_na_pos.*.tsv")
neg_results <- list.files(path = file.path(getwd(), gsea_file[1]), pattern = "gsea_report_for_na_neg.*.tsv")
pos_results <- read.table(file = file.path(getwd(), gsea_file[1], pos_results), header = TRUE, sep = "\t", fill = TRUE, stringsAsFactors = FALSE)
neg_results <- read.table(file = file.path(getwd(), gsea_file[1], neg_results), header = TRUE, sep = "\t", fill = TRUE, stringsAsFactors = FALSE)
# show the top upreguated gene sets after FX1 treatment
columns_to_show <- c("NAME", "SIZE", "ES", "NES", "FDR.q.val", "LEADING.EDGE")
knitr::kable(head(pos_results[, columns_to_show]), caption = "Table 1: Top Upregulated Gene Sets after FX1 Treatment")
Table 1: Top Upregulated Gene Sets after FX1 Treatment
| REGULATION OF TRANSCRIPTION FROM RNA POLYMERASE II PROMOTER IN RESPONSE TO STRESS%GOBP%GO:0043618 |
36 |
0.7502288 |
2.403553 |
0.0000000 |
tags=39%, list=8%, signal=42% |
| RESPONSE TO HEAT%GOBP%GO:0009408 |
47 |
0.7099711 |
2.393108 |
0.0000000 |
tags=30%, list=8%, signal=32% |
| HALLMARK_TNFA_SIGNALING_VIA_NFKB%MSIGDB_C2%HALLMARK_TNFA_SIGNALING_VIA_NFKB |
149 |
0.5951452 |
2.366601 |
0.0000000 |
tags=39%, list=12%, signal=44% |
| AUTOPHAGOSOME ASSEMBLY%GOBP%GO:0000045 |
58 |
0.6602956 |
2.326903 |
0.0004769 |
tags=52%, list=15%, signal=61% |
| MITOCHONDRION DISASSEMBLY%GOBP%GO:0061726 |
45 |
0.6988647 |
2.316348 |
0.0003815 |
tags=53%, list=16%, signal=63% |
| AUTOPHAGY OF MITOCHONDRION%GOBP%GO:0000422 |
45 |
0.6988647 |
2.299817 |
0.0003179 |
tags=53%, list=16%, signal=63% |
2.5: The top downregulated pathway and their FDR q-value are shown from the GSEA.
knitr::kable(head(neg_results[, columns_to_show]), caption = "Table 2: Top Donwregulated Gene Sets after FX1 Treatment")
Table 2: Top Donwregulated Gene Sets after FX1 Treatment
| HALLMARK_MYC_TARGETS_V2%MSIGDB_C2%HALLMARK_MYC_TARGETS_V2 |
45 |
-0.7422627 |
-1.978210 |
0.0007665 |
tags=80%, list=24%, signal=105% |
| IMMUNOREGULATORY INTERACTIONS BETWEEN A LYMPHOID AND A NON-LYMPHOID CELL%REACTOME%R-HSA-198933.7 |
76 |
-0.6526797 |
-1.857991 |
0.0375501 |
tags=50%, list=15%, signal=59% |
| FOLIC ACID-CONTAINING COMPOUND METABOLIC PROCESS%GOBP%GO:0006760 |
18 |
-0.8207158 |
-1.850802 |
0.0314246 |
tags=44%, list=10%, signal=49% |
| PYRIMIDINE METABOLISM%WIKIPATHWAYS_20220310%WP4022%HOMO SAPIENS |
64 |
-0.6666326 |
-1.841201 |
0.0300968 |
tags=53%, list=22%, signal=68% |
| PTERIDINE-CONTAINING COMPOUND METABOLIC PROCESS%GOBP%GO:0042558 |
20 |
-0.8014464 |
-1.827059 |
0.0355922 |
tags=40%, list=6%, signal=42% |
| RIBOSOMAL LARGE SUBUNIT BIOGENESIS%GOBP%GO:0042273 |
64 |
-0.6530314 |
-1.818418 |
0.0363110 |
tags=61%, list=28%, signal=84% |
Non-thresholded analysis vs. thersholded analysis from Assignment 2
There are some noticeable differences between the GSEA results and the thresholded analysis. First, by specifying a threshold value, the gene pathway results were limited to a smaller cohort of genes. As such, while the top upregulated genes using a threshold ORA were regulation of macroautophagy and response to poorly folded and unfolded proteins, in the GSEA, the top upregualted gene sets are regulation of transcription and response to heat. They both do share the upregulation of the authopahgy pathway, with authophagosome assembly being upregulated in GSEA.
The same can be said for downregulated genes, where the threshold ORA had rRNA processing and nucleoside metabolism as top hits, whereas GSEA has MYC targets, and immunoregulatory interactions, along with pyrimidine metabolism. In short, GSEA has more diverse gene sets that are significantly regulated, whereas the threshold ORA is more focused.
Visulization of Gene Set Enrichment Analysis in Cytoscape
The following analysis was performed in Cytoscape, following the referenced pipleline (Reimand & Isserlin et al).
There are 219 nodes, which represent gene sets, and 324 edges, representing the number of genes that are common between the gene sets. A node cutoff value of 0.1 (Q-Value) was used and an edge cutoff valye of 0.375 was used.
The annotated and publishable enrichment map above was manually annotated with red nodes representing upregulated pathway and blue nodes representing downregulated pathways following FX1 treatment. I manually annotated nodes that were large and had a significant function in relation to the experiments performed. The same parameters as described above were kept.
The major themes in the network were identified using AutoAnnotate in Cytoscape (Kucera et al., 2016). The MCL Cluster algorthim was used and then the clusters were manually adjusted to highlight the most significant themes. As seen above, some major themes are carried over from our threshold ORA and GSEA, such as the response to incorrectly folded proteins. In addition, cell death networks like apoptosis and autophagy and cellular degerneartion pathways are also seen, which is within the context of the experiments conducted, as FX1 treatment leads to AML cell death. Some additional themes have been identified, such as pdgfr and fgfr3 pathways which will require further analysis.
Interpretation and Detailed View of Results
Do the enrichment results support conclusions or mechanisms discussed in the original paper (and supporting evidence)?
As was the case with the threshold ORA, the enrichment are in line with the findings of the original paper, but do not go all way. For instance, the paper identified BCL6 as a mediator of chemoresistance in AML cells, however, BCL6 expression is related to ROS modulation and apoptosis (Kurosu et al., 2003). In our case, we observed significant upregulation in the various authophagy pathways along with the TLR8 pathway. In addition, the TLR7/8 pathway could indicate the mechanisms by which FX1 treated AML cells become sensitive to treatment, as T-Cell response might lead to increased TLR signaling and a combined autophagic/apoptotic mechanism of cell death (Lin et al., 2019).
In comparison to the thresholded methods, these results provide a greater picture into the mechanisms that may be occuring, and thus, providing more future points of research and intervention as well.
TRAF6-Myd88 Dependent TLR Pathway in Greater Detail
The figure above, obtained from Reactome Pathway viewer, showcases the induction of the TRAF6/NFkB pathway from the Toll-like receptors 7 and 8.
The zoomed in view highlights how TRAF6 interacts with the IRAK pathways for downstream cellular signaling.
The figure above was created using GeneMANIA, where the the genes that interact with TRAF6 and are found in the leading edge are mapped. Most of the upregulated genes (darker red) are found in the NFkB signalling pathway, indicating a role in the maintenance of chemoresistnace. This is especially intriguing as a recent study showed that disregultion in the TRAF6 signaling pathway can promote clonal hematopoiesis of indeterminate potential, a pre-leukemic condition that allows clones of hematopoietic stem cells to develop into hematological malignancies (Muto et al., 2022).
References
Isserlin, R. (n.d.). Enrichment Map Analysis Pipeline. Bader Lab GitHub.
Isserlin, R. (n.d.). Lecture 10 - Recap and GSEA. BCB420 - Computational Systems Biology.
Isserlin, R. (n.d.). Lecture 11 - Enrichment Mao and other Cytoscpae Apps. BCB420 - Computational Systems Biology.
Kucera, M., Isserlin, R., Arkhangorodsky, A., & Bader, G. D. (2016). AutoAnnotate: A Cytoscape app for summarizing networks with Semantic Annotations. F1000Research, 5, 1717. https://doi.org/10.12688/f1000research.9090.1
Kurosu, T., Fukuda, T., Miki, T., & Miura, O. (2003). BCL6 overexpression prevents increase in reactive oxygen species and inhibits apoptosis induced by chemotherapeutic reagents in B-cell lymphoma cells. Oncogene, 22(29), 4459–4468. https://doi.org/10.1038/sj.onc.1206755 Lin, C.-T., Hsieh, Y.-T., Yang, Y.-J., Chen, S.-H., Wu, C.-H., & Hwang, L.-H. (2019). B-cell lymphoma 6 (BCL6) is a host restriction factor that can suppress HBV gene expression and modulate immune responses. Frontiers in Microbiology, 9. https://doi.org/10.3389/fmicb.2018.03253
Muto, T., Guillamot, M., Yeung, J., Fang, J., Bennett, J., Nadorp, B., Lasry, A., Redondo, L. Z., Choi, K., Gong, Y., Walker, C. S., Hueneman, K., Bolanos, L. C., Barreyro, L., Lee, L. H., Greis, K. D., Vasyliev, N., Khodadadi-Jamayran, A., Nudler, E., … Starczynowski, D. T. (2022). TRAF6 functions as a tumor suppressor in myeloid malignancies by directly targeting MYC oncogenic activity. Cell Stem Cell, 29(2). https://doi.org/10.1016/j.stem.2021.12.007
Reimand, J., Isserlin, R., Voisin, V., Kucera, M., Tannus-Lopes, C., Rostamianfar, A., Wadi, L., Meyer, M., Wong, J., Xu, C., Merico, D., & Bader, G. D. (2019). Pathway enrichment analysis and visualization of OMICS data using G:Profiler, GSEA, Cytoscape and EnrichmentMap. Nature Protocols, 14(2), 482–517. https://doi.org/10.1038/s41596-018-0103-9
LS0tCnRpdGxlOiAiQXNzaWdubWVudCAzOiBEYXRhc2V0IFBhdGh3YXkgYW5kIE5ldHdvcmsgQW5hbHlzaXMiCmF1dGhvcjogIkFiZHVsYSBNYWhlciIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKLS0tCgojIyBJbnRyb2R1Y3Rpb24KVGhlIEdTRTEzMzExMiBkYXRhc2V0IHdhcyBkb3dubG9hZGVkIGZyb20gR0VPIHVzaW5nIHRoZSBHRU9tZXRhZGIgcGFja2FnZS4gVGhlIGRhdGFzZXQgY29udGFpbnMgUk5BLXNlcSByZXN1bHRzIGZyb20gcHJpbWFyeSBBTUwgY2VsbHMgKEFNTDM3KSB0cmVhdGVkIHdpdGggYSBCQ0w2IGluaGliaXRvciAoRlgxKSwgb3IgRE1TTyBhbmQgbm90IHRyZWF0ZWQgc2FtcGxlcyBhcyBjb250cm9scy4gSXQgd2FzIGZpbHRlcmVkIGZvciByZWFkIGNvdW50cyBhbmQgbm9ybWFsaXplZCB1c2luZyB0aGUgVE1NIG1ldGhvZC4gUHJldmlvdXNseSwgZGlmZmVyZW50aWFsIGdlbmUgZXhwcmVzc2lvbiBhbmFseXNpcyB1c2luZyB0aGUgZXhhY3RUZXN0IG1ldGhvZCBhbmQgYW4gb3ZlcnJlcHJlc2VudGF0aW9uIGFuYWx5c2lzIHdhcyBwZXJmb21yZWQgdG8gdmlzdWFsaXplIHRoZSB0b3AgZ2VuZSBoaXRzICgyODcxIGdlbmVzIGF0IHAgPCAwLjAwMDEpIGluIHRoZSBGWDEgdHJlYXRtZW50IHZzLiB1bnRyZWF0ZWQgZ3JvdXBzLgoKIyMgU2V0dXA6IENhbGwgUGFja2FnZXMgYW5kIFNvdXJjZSBEYXRhCgoqKkluc3RhbGwgdGhlIHJlcXVpcmVkIHBhY2thZ2VzIGFuZCBzb3VyY2UgdGhlIHJlcXVpcmVkIGRhdGEgZnJvbSBBc3NpZ25tZW50IDEqKgoKMS4xOiBUaGUgcmVxdWlyZWQgcGFja2FnZXMgYXJlIGluc3RhbGxlZCBpZiB0aGV5IGFyZSBub3QgYWxyZWFkeSBwcmVzZW50LiBOZXh0LCBhbGwgb2YgdGhlIHBhY2thZ2VzIHRoYXQgd2lsbCBiZSB1c2VkIHN1YnNlcXVlbnRseSBhcmUgbG9hZGVkLgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQppZiAoIXJlcXVpcmVOYW1lc3BhY2UoIkNvbXBsZXhIZWF0bWFwIiwgcXVpZXRseSA9IFRSVUUpKQogIGluc3RhbGwucGFja2FnZXMoIkNvbXBsZXhIZWF0bWFwIikKCmlmICghcmVxdWlyZU5hbWVzcGFjZSgiY2lyY2xpemUiLCBxdWlldGx5ID0gVFJVRSkpCiAgaW5zdGFsbC5wYWNrYWdlcygiY2lyY2xpemUiKQoKaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJlZGdlUiIsIHF1aWV0bHkgPSBUUlVFKSkKICBpbnN0YWxsLnBhY2thZ2VzKCJlZGdlUiIpCgppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImdwcm9maWxlcjIiLCBxdWlldGx5ID0gVFJVRSkpCiAgaW5zdGFsbC5wYWNrYWdlcygiZ3Byb2ZpbGVyMiIpCgppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImdncGxvdDIiLCBxdWlldGx5ID0gVFJVRSkpCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpCgppZiAoIXJlcXVpcmVOYW1lc3BhY2UoImdncmVwZWwiLCBxdWlldGx5ID0gVFJVRSkpCiAgaW5zdGFsbC5wYWNrYWdlcygiZ2dyZXBlbCIpCgppZiAoIXJlcXVpcmVOYW1lc3BhY2UoIlJDdXJsIiwgcXVpZXRseSA9IFRSVUUpKQogIGluc3RhbGwucGFja2FnZXMoIlJDdXJsIikKCmlmICghcmVxdWlyZU5hbWVzcGFjZSgiQmlvY01hbmFnZXIiLCBxdWlldGx5ID0gVFJVRSkpCiAgaW5zdGFsbC5wYWNrYWdlcygiQmlvY01hbmFnZXIiKQoKaWYgKCFyZXF1aXJlTmFtZXNwYWNlKCJSQ3kzIiwgcXVpZXRseSA9IFRSVUUpKQogIGluc3RhbGwucGFja2FnZXMoIlJDeTMiKQoKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoQ29tcGxleEhlYXRtYXApKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShjaXJjbGl6ZSkpCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGVkZ2VSKSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoZ3Byb2ZpbGVyMikpCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGdncGxvdDIpKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShnZ3JlcGVsKSkKc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkoUkN1cmwpKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShCaW9jTWFuYWdlcikpCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KFJDeTMpKQpgYGAKCjEuMiBUaGUgdmFyaWFibGVzIGZyb20gQXNzaWdubWVudC0yIGFyZSBrbml0dGVkIGFzIHRoZSByYW5rZWQgZmlsZSB3aWxsIGJlIHVzZWQgZm9yIGRvd25zdHJlYW0gYW5hbHlzZXMuCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9Cm9wdGlvbnMoa25pdHIuZHVwbGljYXRlLmxhYmVsID0gImFsbG93IikKcmVzIDwtIGtuaXRyOjprbml0X2NoaWxkKGZpbGUucGF0aCgnQTJfQWJkdWxhTWFoZXIuUm1kJykpCmBgYAoKCiMjIE5vbi1UaHJlc2hvbGRlZCBHZW5lIFNldCBFbnJpY2htZW50IEFuYWx5c2lzCgoqKldoYXQgbWV0aG9kIGRpZCB5b3UgdXNlPyBXaGF0IGdlbmVzZXRzIGRpZCB5b3UgdXNlPyoqCgpJIHVzZWQgR2VuZSBTZXQgRW5yaWNobWVudCBBbmFseXNpcyB0aGF0IGlzIGF2YWlhbGJsZSB0aHJvdWdoIHRoZSBHU0VBIEphdmEgc29mdHdhcmUgYW5kIHRoZSBlbnJpY2htZW50IG1hcCBwcm90b2NvbCBwaXBlbGluZSBmcm9tIHRoZSBCYWRlciBMYWIgKElzc2VybGluLCAyMDIwKS4gSSB1c2VkIHRoZSBodW1hbiBnZW5lIHNldCBhdmFpbGFibGUgZnJvbSB0aGUgQmFkZXIgTGFiLgoKMi4xIEFuIHVwZGF0ZWQgZ2VuZXNldCBmaWxlIGlzIG9idGFpbmVkIGZyb20gdGhlIEJhZGVyIExhYiBhbmQgc3RvcmVkIGluIHRoZSB3b3JraW5nIGRpcmVjdG9yeS4gVGhpcyBmaWxlIHdpbGwgYmUgdXNlZCBpbiB0aGUgR1NFQS4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBjb2RlIGFkYXB0ZWQgZnJvbSBsZWN0dXJlIDEwCmdtdF91cmwgPSAiaHR0cDovL2Rvd25sb2FkLmJhZGVybGFiLm9yZy9FTV9HZW5lc2V0cy9jdXJyZW50X3JlbGVhc2UvSHVtYW4vc3ltYm9sLyIKCiMgbGlzdCBhbGwgdGhlIGZpbGVzIG9uIHRoZSBzZXJ2ZXIKZmlsZW5hbWVzID0gZ2V0VVJMKGdtdF91cmwpCnRjID0gdGV4dENvbm5lY3Rpb24oZmlsZW5hbWVzKQpjb250ZW50cyA9IHJlYWRMaW5lcyh0YykKY2xvc2UodGMpCgojIGdldCB0aGUgZ210IHRoYXQgaGFzIGFsbCB0aGUgcGF0aHdheXMgYW5kIGRvZXMgbm90IGluY2x1ZGUgdGVybXMgaW5mZXJyZWQKIyBmcm9tIGVsZWN0cm9uaWMgYW5ub3RhdGlvbnMoSUVBKSBzdGFydCB3aXRoIGdtdCBmaWxlIHRoYXQgaGFzIHBhdGh3YXlzIG9ubHkKcnggPSBncmVnZXhwcigiKD88PTxhIGhyZWY9XCIpKC4qLkdPQlBfQWxsUGF0aHdheXNfbm9fR09faWVhLiouKSguZ210KSg/PVwiPikiLCBjb250ZW50cywKICAgIHBlcmwgPSBUUlVFKQoKIyBzZXQgdG8gY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeQpkYXRhX2RpciA9ICIvaG9tZS9yc3R1ZGlvL3Byb2plY3RzIgoKZ210X2ZpbGUgPSB1bmxpc3QocmVnbWF0Y2hlcyhjb250ZW50cywgcngpKQpkZXN0X2dtdF9maWxlIDwtIGZpbGUucGF0aChkYXRhX2RpciwgZ210X2ZpbGUpCmRvd25sb2FkLmZpbGUocGFzdGUoZ210X3VybCwgZ210X2ZpbGUsIHNlcCA9ICIiKSwgZGVzdGZpbGUgPSBkZXN0X2dtdF9maWxlKQpgYGAKCjIuMjogVGhlIHJhbmtlZCBsaXN0IGNyZWF0ZWQgaW4gQXNzaWdubW5lbnQtMiBpcyBzdG9yZWQgYXMgYSAucm5rIGZpbGUgaW4gdGhlIHdvcmtpbmcgZGlyZWN0b3J5LgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp3cml0ZS50YWJsZSh4PWRhdGEuZnJhbWUoZ2VuZW5hbWUgPSBoaXRzX2duJEdlbmVpZCwgRl9zdGF0PWhpdHNfZ24kcmFuayksCiAgICAgICAgICAgIGZpbGU9ZmlsZS5wYXRoKCIvaG9tZS9yc3R1ZGlvL3Byb2plY3RzIiwgImV4cHJlc3Npb24ucm5rIiksIHNlcCA9Ilx0IiwKICAgICAgICAgICAgcm93Lm5hbWVzID0gRkFMU0UsIGNvbC5uYW1lcyA9IEZBTFNFLCBxdW90ZSA9IEZBTFNFKQpgYGAKCjIuMzogR1NFQSBpcyBwZXJmb3JtZWQgb24gdGhlIHJhbmtlZCBnZW5lIHNldCB1c2luZyB0aGUgZW5yaWNobWVudCBtYXAgcHJvdG9jb2wgcGlwZWxpbmUgZnJvbSB0aGUgQmFkZXIgTGFiIChJc3NlcmxpbiwgMjAyMCkuIFRoZSBmb2xsb3dpbmcgcGFyYW1ldGVycyB3ZXJlIHNwZWNpZmllZC4gMTAwMCBwZXJtdWF0aW9ucyB3ZXJlIHJ1bi4KClRoZSBmb2xsb3dpbmcgY29kZSB3YXMgcnVuIG9uIHRoZSBHU0VBIERvY2tlciAocmlzc2VybGluL2VtX2Jhc2VfaW1hZ2UpLgpgYGB7dW5kZWZpbmVkIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiNybmsgPC0gcmVhZC50YWJsZSgiZngxX3JhbmtlZF9nZW5lbGlzdC50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXI9VFJVRSkKCiN3cml0ZS50YWJsZShybmssIGZpbGU9ImV4cHJlc3Npb24ucm5rIiwgcXVvdGU9RkFMU0UsIHNlcD0iXHQiLCByb3cubmFtZXM9RkFMU0UpCgojIHNwZWNpZnkgdGhlIGphdmFfdmVyc2lvbgojcnVuX2dzZWEgPC0gVFJVRQojamF2YV92ZXJzaW9uID0gIjExIgoKIyBzZXQgdGhlIGxvY2F0aW9uIG9mIHRoZSBHU0VBIGphdmEgZmlsZSBhbmQgc3BlY2lmaXkgdGhlIHdvcmtpbmcgZGlyZWN0b3J5CiNnc2VhX2phciA8LSAiL2hvbWUvcnN0dWRpby9HU0VBXzQuMS4wL2dzZWEtY2xpLnNoIgojd29ya2luZ19kaXIgPC0gIi9ob21lL3JzdHVkaW8vcHJvamVjdHMiCgojIHNwZWNpZnkgdGhlIHJhbmtlZCBhbmQgb3V0cHV0IGFuYWx5c2lzIGZpbGUKI3Jua19maWxlIDwtICJleHByZXNzaW9uLnJuayIKI2FuYWx5c2lzX25hbWUgPC0gIkEzX0ZYMV9SZXN1bHRzIgoKIyBydW4gR1NFQQojaWYocnVuX2dzZWEgJiYgamF2YV92ZXJzaW9uID09ICIxMSIpewojICBjb21tYW5kIDwtIHBhc3RlKCIiLGdzZWFfamFyLCAgIkdTRUFQcmVSYW5rZWQgLWdteCIsIGRlc3RfZ210X2ZpbGUsICItcm5rIiAsZmlsZS5wYXRoKHdvcmtpbmdfZGlyLHJua19maWxlKSwgIi1jb2xsYXBzZSBmYWxzZSAtbnBlcm0gMTAwMCAtc2NvcmluZ19zY2hlbWUgd2VpZ2h0ZWQgLXJwdF9sYWJlbCAiLGFuYWx5c2lzX25hbWUsIiAgLXBsb3RfdG9wX3ggMjAgLXJuZF9zZWVkIDEyMzQ1ICAtc2V0X21heCAyMDAgLXNldF9taW4gMTUgLXppcF9yZXBvcnQgZmFsc2UgLW91dCIgLHdvcmtpbmdfZGlyLCAiID4gZ3NlYV9vdXRwdXQudHh0IixzZXA9IiAiKQojICBzeXN0ZW0oY29tbWFuZCkKI30gZWxzZSBpZiAocnVuX2dzZWEpIHsKIyAgY29tbWFuZCA8LSBwYXN0ZSgiamF2YSAgLVhteDFHIC1jcCIsZ3NlYV9qYXIsICAieHRvb2xzLmdzZWEuR3NlYVByZXJhbmtlZCAtZ214IiwgZGVzdF9nbXRfZmlsZSwgIi1ybmsiICxmaWxlLnBhdGgod29ya2luZ19kaXIscm5rX2ZpbGUpLCAiLWNvbGxhcHNlIGZhbHNlIC1ucGVybSAxMDAwIC1wZXJtdXRlIGdlbmVfc2V0IC1zY29yaW5nX3NjaGVtZSB3ZWlnaHRlZCAtcnB0X2xhYmVsICIsYW5hbHlzaXNfbmFtZSwiICAtbnVtIDEwMCAtcGxvdF90b3BfeCAyMCAtcm5kX3NlZWQgMTIzNDUgIC1zZXRfbWF4IDIwMCAtc2V0X21pbiAxNSAtemlwX3JlcG9ydCBmYWxzZSAtb3V0IiAsd29ya2luZ19kaXIsICItZ3VpIGZhbHNlID4gZ3NlYV9vdXRwdXQudHh0IixzZXA9IiAiKQojICBzeXN0ZW0oY29tbWFuZCkKI30KYGBgCgoqKlN1bW1hcnkgb2YgRW5yaWNobWVudCBSZXN1bHRzKioKCjIuNDogVGhlIHRvcCB1cHJlZ3VsYXRlZCBwYXRod2F5IGFuZCB0aGVpciBGRFIgcS12YWx1ZSBhcmUgc2hvd24gZnJvbSB0aGUgR1NFQS4KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZ3NlYV9maWxlIDwtIGxpc3QuZmlsZXMocGF0aCA9IGdldHdkKCksIHBhdHRlcm4gPSAiXFwuR3NlYVByZXJhbmtlZCIpCgojIHJlYWQgdGhlIHRvcCBwb3NpdGl2ZWx5IGFuZCBuZWdhdGl2ZWx5IHJlZ3VsYXRlZCBnZW5lcyBmcm9tIHRoZSBHU0VBCnBvc19yZXN1bHRzIDwtIGxpc3QuZmlsZXMocGF0aCA9IGZpbGUucGF0aChnZXR3ZCgpLCBnc2VhX2ZpbGVbMV0pLCBwYXR0ZXJuID0gImdzZWFfcmVwb3J0X2Zvcl9uYV9wb3MuKi50c3YiKQpuZWdfcmVzdWx0cyA8LSBsaXN0LmZpbGVzKHBhdGggPSBmaWxlLnBhdGgoZ2V0d2QoKSwgZ3NlYV9maWxlWzFdKSwgcGF0dGVybiA9ICJnc2VhX3JlcG9ydF9mb3JfbmFfbmVnLioudHN2IikKcG9zX3Jlc3VsdHMgPC0gcmVhZC50YWJsZShmaWxlID0gZmlsZS5wYXRoKGdldHdkKCksIGdzZWFfZmlsZVsxXSwgcG9zX3Jlc3VsdHMpLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAiXHQiLCBmaWxsID0gVFJVRSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQpuZWdfcmVzdWx0cyA8LSByZWFkLnRhYmxlKGZpbGUgPSBmaWxlLnBhdGgoZ2V0d2QoKSwgZ3NlYV9maWxlWzFdLCBuZWdfcmVzdWx0cyksIGhlYWRlciA9IFRSVUUsIHNlcCA9ICJcdCIsIGZpbGwgPSBUUlVFLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCgojIHNob3cgdGhlIHRvcCB1cHJlZ3VhdGVkIGdlbmUgc2V0cyBhZnRlciBGWDEgdHJlYXRtZW50CmNvbHVtbnNfdG9fc2hvdyA8LSBjKCJOQU1FIiwgIlNJWkUiLCAiRVMiLCAiTkVTIiwgIkZEUi5xLnZhbCIsICJMRUFESU5HLkVER0UiKQprbml0cjo6a2FibGUoaGVhZChwb3NfcmVzdWx0c1ssIGNvbHVtbnNfdG9fc2hvd10pLCBjYXB0aW9uID0gIlRhYmxlIDE6IFRvcCBVcHJlZ3VsYXRlZCBHZW5lIFNldHMgYWZ0ZXIgRlgxIFRyZWF0bWVudCIpCmBgYAoKMi41OiBUaGUgdG9wIGRvd25yZWd1bGF0ZWQgcGF0aHdheSBhbmQgdGhlaXIgRkRSIHEtdmFsdWUgYXJlIHNob3duIGZyb20gdGhlIEdTRUEuCmBgYHtyfQprbml0cjo6a2FibGUoaGVhZChuZWdfcmVzdWx0c1ssIGNvbHVtbnNfdG9fc2hvd10pLCBjYXB0aW9uID0gIlRhYmxlIDI6IFRvcCBEb253cmVndWxhdGVkIEdlbmUgU2V0cyBhZnRlciBGWDEgVHJlYXRtZW50IikKYGBgCgoqKk5vbi10aHJlc2hvbGRlZCBhbmFseXNpcyB2cy4gdGhlcnNob2xkZWQgYW5hbHlzaXMgZnJvbSBBc3NpZ25tZW50IDIqKgoKVGhlcmUgYXJlIHNvbWUgbm90aWNlYWJsZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBHU0VBIHJlc3VsdHMgYW5kIHRoZSB0aHJlc2hvbGRlZCBhbmFseXNpcy4gRmlyc3QsIGJ5IHNwZWNpZnlpbmcgYSB0aHJlc2hvbGQgdmFsdWUsIHRoZSBnZW5lIHBhdGh3YXkgcmVzdWx0cyB3ZXJlIGxpbWl0ZWQgdG8gYSBzbWFsbGVyIGNvaG9ydCBvZiBnZW5lcy4gQXMgc3VjaCwgd2hpbGUgdGhlIHRvcCB1cHJlZ3VsYXRlZCBnZW5lcyB1c2luZyBhIHRocmVzaG9sZCBPUkEgd2VyZSByZWd1bGF0aW9uIG9mIG1hY3JvYXV0b3BoYWd5IGFuZCByZXNwb25zZSB0byBwb29ybHkgZm9sZGVkIGFuZCB1bmZvbGRlZCBwcm90ZWlucywgaW4gdGhlIEdTRUEsIHRoZSB0b3AgdXByZWd1YWx0ZWQgZ2VuZSBzZXRzIGFyZSByZWd1bGF0aW9uIG9mIHRyYW5zY3JpcHRpb24gYW5kIHJlc3BvbnNlIHRvIGhlYXQuIFRoZXkgYm90aCBkbyBzaGFyZSB0aGUgdXByZWd1bGF0aW9uIG9mIHRoZSBhdXRob3BhaGd5IHBhdGh3YXksIHdpdGggYXV0aG9waGFnb3NvbWUgYXNzZW1ibHkgYmVpbmcgdXByZWd1bGF0ZWQgaW4gR1NFQS4KClRoZSBzYW1lIGNhbiBiZSBzYWlkIGZvciBkb3ducmVndWxhdGVkIGdlbmVzLCB3aGVyZSB0aGUgdGhyZXNob2xkIE9SQSBoYWQgclJOQSBwcm9jZXNzaW5nIGFuZCBudWNsZW9zaWRlIG1ldGFib2xpc20gYXMgdG9wIGhpdHMsIHdoZXJlYXMgR1NFQSBoYXMgTVlDIHRhcmdldHMsIGFuZCBpbW11bm9yZWd1bGF0b3J5IGludGVyYWN0aW9ucywgYWxvbmcgd2l0aCBweXJpbWlkaW5lIG1ldGFib2xpc20uIEluIHNob3J0LCBHU0VBIGhhcyBtb3JlIGRpdmVyc2UgZ2VuZSBzZXRzIHRoYXQgYXJlIHNpZ25pZmljYW50bHkgcmVndWxhdGVkLCB3aGVyZWFzIHRoZSB0aHJlc2hvbGQgT1JBIGlzIG1vcmUgZm9jdXNlZC4KCiMjIFZpc3VsaXphdGlvbiBvZiBHZW5lIFNldCBFbnJpY2htZW50IEFuYWx5c2lzIGluIEN5dG9zY2FwZQoKVGhlIGZvbGxvd2luZyBhbmFseXNpcyB3YXMgcGVyZm9ybWVkIGluIEN5dG9zY2FwZSwgZm9sbG93aW5nIHRoZSByZWZlcmVuY2VkIHBpcGxlbGluZSAoUmVpbWFuZCAmIElzc2VybGluIGV0IGFsKS4KCiFbMy4xOiBDeXRvc2NhcGUgRW5yaWNobWVudCBNYXBdKC9ob21lL3JzdHVkaW8vcHJvamVjdHMvQTNfZmlndXJlcy9BM19GWDFfRW5yaWNobWVudE1hcC5wbmcpClRoZXJlIGFyZSAyMTkgbm9kZXMsIHdoaWNoIHJlcHJlc2VudCBnZW5lIHNldHMsIGFuZCAzMjQgZWRnZXMsIHJlcHJlc2VudGluZyB0aGUgbnVtYmVyIG9mIGdlbmVzIHRoYXQgYXJlIGNvbW1vbiBiZXR3ZWVuIHRoZSBnZW5lIHNldHMuIEEgbm9kZSBjdXRvZmYgdmFsdWUgb2YgMC4xIChRLVZhbHVlKSB3YXMgdXNlZCBhbmQgYW4gZWRnZSBjdXRvZmYgdmFseWUgb2YgMC4zNzUgd2FzIHVzZWQuCgohW0Fubm90YXRlZCBFbnJpY2htZW50IE1hcF0oL2hvbWUvcnN0dWRpby9wcm9qZWN0cy9BM19maWd1cmVzL0EzX0ZYMV9QdWJsaXNoX0ZpZ3VyZS5wbmcpClRoZSBhbm5vdGF0ZWQgYW5kIHB1Ymxpc2hhYmxlIGVucmljaG1lbnQgbWFwIGFib3ZlIHdhcyBtYW51YWxseSBhbm5vdGF0ZWQgd2l0aCByZWQgbm9kZXMgcmVwcmVzZW50aW5nIHVwcmVndWxhdGVkIHBhdGh3YXkgYW5kIGJsdWUgbm9kZXMgcmVwcmVzZW50aW5nIGRvd25yZWd1bGF0ZWQgcGF0aHdheXMgZm9sbG93aW5nIEZYMSB0cmVhdG1lbnQuIEkgbWFudWFsbHkgYW5ub3RhdGVkIG5vZGVzIHRoYXQgd2VyZSBsYXJnZSBhbmQgaGFkIGEgc2lnbmlmaWNhbnQgZnVuY3Rpb24gaW4gcmVsYXRpb24gdG8gdGhlIGV4cGVyaW1lbnRzIHBlcmZvcm1lZC4gVGhlIHNhbWUgcGFyYW1ldGVycyBhcyBkZXNjcmliZWQgYWJvdmUgd2VyZSBrZXB0LgoKIVtUaGVtZSBOZXR3b3JrXSgvaG9tZS9yc3R1ZGlvL3Byb2plY3RzL0EzX2ZpZ3VyZXMvQTNfRlgxX1RoZW1lcy5wbmcpClRoZSBtYWpvciB0aGVtZXMgaW4gdGhlIG5ldHdvcmsgd2VyZSBpZGVudGlmaWVkIHVzaW5nIEF1dG9Bbm5vdGF0ZSBpbiBDeXRvc2NhcGUgKEt1Y2VyYSBldCBhbC4sIDIwMTYpLiBUaGUgTUNMIENsdXN0ZXIgYWxnb3J0aGltIHdhcyB1c2VkIGFuZCB0aGVuIHRoZSBjbHVzdGVycyB3ZXJlIG1hbnVhbGx5IGFkanVzdGVkIHRvIGhpZ2hsaWdodCB0aGUgbW9zdCBzaWduaWZpY2FudCB0aGVtZXMuIEFzIHNlZW4gYWJvdmUsIHNvbWUgbWFqb3IgdGhlbWVzIGFyZSBjYXJyaWVkIG92ZXIgZnJvbSBvdXIgdGhyZXNob2xkIE9SQSBhbmQgR1NFQSwgc3VjaCBhcyB0aGUgcmVzcG9uc2UgdG8gaW5jb3JyZWN0bHkgZm9sZGVkIHByb3RlaW5zLiBJbiBhZGRpdGlvbiwgY2VsbCBkZWF0aCBuZXR3b3JrcyBsaWtlIGFwb3B0b3NpcyBhbmQgYXV0b3BoYWd5IGFuZCBjZWxsdWxhciBkZWdlcm5lYXJ0aW9uIHBhdGh3YXlzIGFyZSBhbHNvIHNlZW4sIHdoaWNoIGlzIHdpdGhpbiB0aGUgY29udGV4dCBvZiB0aGUgZXhwZXJpbWVudHMgY29uZHVjdGVkLCBhcyBGWDEgdHJlYXRtZW50IGxlYWRzIHRvIEFNTCBjZWxsIGRlYXRoLiBTb21lIGFkZGl0aW9uYWwgdGhlbWVzIGhhdmUgYmVlbiBpZGVudGlmaWVkLCBzdWNoIGFzIHBkZ2ZyIGFuZCBmZ2ZyMyBwYXRod2F5cyB3aGljaCB3aWxsIHJlcXVpcmUgZnVydGhlciBhbmFseXNpcy4KCiMjIEludGVycHJldGF0aW9uIGFuZCBEZXRhaWxlZCBWaWV3IG9mIFJlc3VsdHMKCioqRG8gdGhlIGVucmljaG1lbnQgcmVzdWx0cyBzdXBwb3J0IGNvbmNsdXNpb25zIG9yIG1lY2hhbmlzbXMgZGlzY3Vzc2VkIGluIHRoZSBvcmlnaW5hbCBwYXBlciAoYW5kIHN1cHBvcnRpbmcgZXZpZGVuY2UpPyoqCgpBcyB3YXMgdGhlIGNhc2Ugd2l0aCB0aGUgdGhyZXNob2xkIE9SQSwgdGhlIGVucmljaG1lbnQgYXJlIGluIGxpbmUgd2l0aCB0aGUgZmluZGluZ3Mgb2YgdGhlIG9yaWdpbmFsIHBhcGVyLCBidXQgZG8gbm90IGdvIGFsbCB3YXkuIEZvciBpbnN0YW5jZSwgdGhlIHBhcGVyIGlkZW50aWZpZWQgQkNMNiBhcyBhIG1lZGlhdG9yIG9mIGNoZW1vcmVzaXN0YW5jZSBpbiBBTUwgY2VsbHMsIGhvd2V2ZXIsIEJDTDYgZXhwcmVzc2lvbiBpcyByZWxhdGVkIHRvIFJPUyBtb2R1bGF0aW9uIGFuZCBhcG9wdG9zaXMgKEt1cm9zdSBldCBhbC4sIDIwMDMpLiBJbiBvdXIgY2FzZSwgd2Ugb2JzZXJ2ZWQgc2lnbmlmaWNhbnQgdXByZWd1bGF0aW9uIGluIHRoZSB2YXJpb3VzIGF1dGhvcGhhZ3kgcGF0aHdheXMgYWxvbmcgd2l0aCB0aGUgVExSOCBwYXRod2F5LiBJbiBhZGRpdGlvbiwgdGhlIFRMUjcvOCBwYXRod2F5IGNvdWxkIGluZGljYXRlIHRoZSBtZWNoYW5pc21zIGJ5IHdoaWNoIEZYMSB0cmVhdGVkIEFNTCBjZWxscyBiZWNvbWUgc2Vuc2l0aXZlIHRvIHRyZWF0bWVudCwgYXMgVC1DZWxsIHJlc3BvbnNlIG1pZ2h0IGxlYWQgdG8gaW5jcmVhc2VkIFRMUiBzaWduYWxpbmcgYW5kIGEgY29tYmluZWQgYXV0b3BoYWdpYy9hcG9wdG90aWMgbWVjaGFuaXNtIG9mIGNlbGwgZGVhdGggKExpbiBldCBhbC4sIDIwMTkpLgoKSW4gY29tcGFyaXNvbiB0byB0aGUgdGhyZXNob2xkZWQgbWV0aG9kcywgdGhlc2UgcmVzdWx0cyBwcm92aWRlIGEgZ3JlYXRlciBwaWN0dXJlIGludG8gdGhlIG1lY2hhbmlzbXMgdGhhdCBtYXkgYmUgb2NjdXJpbmcsIGFuZCB0aHVzLCBwcm92aWRpbmcgbW9yZSBmdXR1cmUgcG9pbnRzIG9mIHJlc2VhcmNoIGFuZCBpbnRlcnZlbnRpb24gYXMgd2VsbC4KCioqVFJBRjYtTXlkODggRGVwZW5kZW50IFRMUiBQYXRod2F5IGluIEdyZWF0ZXIgRGV0YWlsKioKIVtUUkFGNiBORmtCIFBhdGh3YXldKC9ob21lL3JzdHVkaW8vcHJvamVjdHMvQTNfZmlndXJlcy9BM19UUkFGNi5wbmcpClRoZSBmaWd1cmUgYWJvdmUsIG9idGFpbmVkIGZyb20gUmVhY3RvbWUgUGF0aHdheSB2aWV3ZXIsIHNob3djYXNlcyB0aGUgaW5kdWN0aW9uIG9mIHRoZSBUUkFGNi9ORmtCIHBhdGh3YXkgZnJvbSB0aGUgVG9sbC1saWtlIHJlY2VwdG9ycyA3IGFuZCA4LgoKIVtUUkFGNiBTaWduYWxsaW5nXSgvaG9tZS9yc3R1ZGlvL3Byb2plY3RzL0EzX2ZpZ3VyZXMvQTNfVFJBRjZfem9vbWVkLnBuZykKVGhlIHpvb21lZCBpbiB2aWV3IGhpZ2hsaWdodHMgaG93IFRSQUY2IGludGVyYWN0cyB3aXRoIHRoZSBJUkFLIHBhdGh3YXlzIGZvciBkb3duc3RyZWFtIGNlbGx1bGFyIHNpZ25hbGluZy4KCiFbVFJBRjYgUGF0aHdheSBNYXBdKC9ob21lL3JzdHVkaW8vcHJvamVjdHMvQTNfZmlndXJlcy9UUkFGNi1nZW5lbWFuaWEucG5nKQpUaGUgZmlndXJlIGFib3ZlIHdhcyBjcmVhdGVkIHVzaW5nIEdlbmVNQU5JQSwgd2hlcmUgdGhlIHRoZSBnZW5lcyB0aGF0IGludGVyYWN0IHdpdGggVFJBRjYgYW5kIGFyZSBmb3VuZCBpbiB0aGUgbGVhZGluZyBlZGdlIGFyZSBtYXBwZWQuIE1vc3Qgb2YgdGhlIHVwcmVndWxhdGVkIGdlbmVzIChkYXJrZXIgcmVkKSBhcmUgZm91bmQgaW4gdGhlIE5Ga0Igc2lnbmFsbGluZyBwYXRod2F5LCBpbmRpY2F0aW5nIGEgcm9sZSBpbiB0aGUgbWFpbnRlbmFuY2Ugb2YgY2hlbW9yZXNpc3RuYWNlLiBUaGlzIGlzIGVzcGVjaWFsbHkgaW50cmlndWluZyBhcyBhIHJlY2VudCBzdHVkeSBzaG93ZWQgdGhhdCBkaXNyZWd1bHRpb24gaW4gdGhlIFRSQUY2IHNpZ25hbGluZyBwYXRod2F5IGNhbiBwcm9tb3RlIGNsb25hbCBoZW1hdG9wb2llc2lzIG9mIGluZGV0ZXJtaW5hdGUgcG90ZW50aWFsLCBhIHByZS1sZXVrZW1pYyBjb25kaXRpb24gdGhhdCBhbGxvd3MgY2xvbmVzIG9mIGhlbWF0b3BvaWV0aWMgc3RlbSBjZWxscyB0byBkZXZlbG9wIGludG8gaGVtYXRvbG9naWNhbCBtYWxpZ25hbmNpZXMgKE11dG8gZXQgYWwuLCAyMDIyKS4KCiMjIFJlZmVyZW5jZXMKCklzc2VybGluLCBSLiAobi5kLikuIEVucmljaG1lbnQgTWFwIEFuYWx5c2lzIFBpcGVsaW5lLiBCYWRlciBMYWIgR2l0SHViLgoKSXNzZXJsaW4sIFIuIChuLmQuKS4gTGVjdHVyZSAxMCAtIFJlY2FwIGFuZCBHU0VBLiBCQ0I0MjAgLSBDb21wdXRhdGlvbmFsIFN5c3RlbXMgQmlvbG9neS4KCklzc2VybGluLCBSLiAobi5kLikuIExlY3R1cmUgMTEgLSBFbnJpY2htZW50IE1hbyBhbmQgb3RoZXIgQ3l0b3NjcGFlIEFwcHMuIEJDQjQyMCAtIENvbXB1dGF0aW9uYWwgU3lzdGVtcyBCaW9sb2d5LgoKS3VjZXJhLCBNLiwgSXNzZXJsaW4sIFIuLCBBcmtoYW5nb3JvZHNreSwgQS4sICZhbXA7IEJhZGVyLCBHLiBELiAoMjAxNikuIEF1dG9Bbm5vdGF0ZTogQSBDeXRvc2NhcGUgYXBwIGZvciBzdW1tYXJpemluZyBuZXR3b3JrcyB3aXRoIFNlbWFudGljIEFubm90YXRpb25zLiBGMTAwMFJlc2VhcmNoLCA1LCAxNzE3LiBodHRwczovL2RvaS5vcmcvMTAuMTI2ODgvZjEwMDByZXNlYXJjaC45MDkwLjEgCgpLdXJvc3UsIFQuLCBGdWt1ZGEsIFQuLCBNaWtpLCBULiwgJmFtcDsgTWl1cmEsIE8uICgyMDAzKS4gQkNMNiBvdmVyZXhwcmVzc2lvbiBwcmV2ZW50cyBpbmNyZWFzZSBpbiByZWFjdGl2ZSBveHlnZW4gc3BlY2llcyBhbmQgaW5oaWJpdHMgYXBvcHRvc2lzIGluZHVjZWQgYnkgY2hlbW90aGVyYXBldXRpYyByZWFnZW50cyBpbiBCLWNlbGwgbHltcGhvbWEgY2VsbHMuIE9uY29nZW5lLCAyMigyOSksIDQ0NTnigJM0NDY4LiBodHRwczovL2RvaS5vcmcvMTAuMTAzOC9zai5vbmMuMTIwNjc1NSAKTGluLCBDLi1ULiwgSHNpZWgsIFkuLVQuLCBZYW5nLCBZLi1KLiwgQ2hlbiwgUy4tSC4sIFd1LCBDLi1ILiwgJmFtcDsgSHdhbmcsIEwuLUguICgyMDE5KS4gQi1jZWxsIGx5bXBob21hIDYgKEJDTDYpIGlzIGEgaG9zdCByZXN0cmljdGlvbiBmYWN0b3IgdGhhdCBjYW4gc3VwcHJlc3MgSEJWIGdlbmUgZXhwcmVzc2lvbiBhbmQgbW9kdWxhdGUgaW1tdW5lIHJlc3BvbnNlcy4gRnJvbnRpZXJzIGluIE1pY3JvYmlvbG9neSwgOS4gaHR0cHM6Ly9kb2kub3JnLzEwLjMzODkvZm1pY2IuMjAxOC4wMzI1MyAKCk11dG8sIFQuLCBHdWlsbGFtb3QsIE0uLCBZZXVuZywgSi4sIEZhbmcsIEouLCBCZW5uZXR0LCBKLiwgTmFkb3JwLCBCLiwgTGFzcnksIEEuLCBSZWRvbmRvLCBMLiBaLiwgQ2hvaSwgSy4sIEdvbmcsIFkuLCBXYWxrZXIsIEMuIFMuLCBIdWVuZW1hbiwgSy4sIEJvbGFub3MsIEwuIEMuLCBCYXJyZXlybywgTC4sIExlZSwgTC4gSC4sIEdyZWlzLCBLLiBELiwgVmFzeWxpZXYsIE4uLCBLaG9kYWRhZGktSmFtYXlyYW4sIEEuLCBOdWRsZXIsIEUuLCDigKYgU3RhcmN6eW5vd3NraSwgRC4gVC4gKDIwMjIpLiBUUkFGNiBmdW5jdGlvbnMgYXMgYSB0dW1vciBzdXBwcmVzc29yIGluIG15ZWxvaWQgbWFsaWduYW5jaWVzIGJ5IGRpcmVjdGx5IHRhcmdldGluZyBNWUMgb25jb2dlbmljIGFjdGl2aXR5LiBDZWxsIFN0ZW0gQ2VsbCwgMjkoMikuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDE2L2ouc3RlbS4yMDIxLjEyLjAwNyAKClJlaW1hbmQsIEouLCBJc3NlcmxpbiwgUi4sIFZvaXNpbiwgVi4sIEt1Y2VyYSwgTS4sIFRhbm51cy1Mb3BlcywgQy4sIFJvc3RhbWlhbmZhciwgQS4sIFdhZGksIEwuLCBNZXllciwgTS4sIFdvbmcsIEouLCBYdSwgQy4sIE1lcmljbywgRC4sICZhbXA7IEJhZGVyLCBHLiBELiAoMjAxOSkuIFBhdGh3YXkgZW5yaWNobWVudCBhbmFseXNpcyBhbmQgdmlzdWFsaXphdGlvbiBvZiBPTUlDUyBkYXRhIHVzaW5nIEc6UHJvZmlsZXIsIEdTRUEsIEN5dG9zY2FwZSBhbmQgRW5yaWNobWVudE1hcC4gTmF0dXJlIFByb3RvY29scywgMTQoMiksIDQ4MuKAkzUxNy4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvczQxNTk2LTAxOC0wMTAzLTkg